<?PHP
	/************************************************************************
	*       This file, in addition to all other parts of X7 Chat are        *
	*                   Copyright 2003-2007 by Tim Chamness.                *
	* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	* Version:          X7 Chat 3.0.0-A2                                    *
	* Release Date:     October 20, 2007                                    *
	* Author:           Tim Chamness                                        *
	* Copyright:        2003-2007 by Tim Chamness                           *
	* Website:          http://www.x7chat.com/                              *
	* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	* X7 Chat 3 is free software; you can redistribute it and/or modify     *
	* it under the terms of the GNU General Public License as published by  *
	* the Free Software Foundation; either version 3 of the License, or     *
	* (at your option) any later version.                                   *
	*                                                                       *
	* X7 Chat 3 is distributed in the hope that it will be useful, but      *
	* WITHOUT ANY WARRANTY; without even the implied warranty of            *
	* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
	* General Public License for more details.                              *
	*                                                                       *
	* You should have received a copy of the GNU General Public License     *
	* along with this program.  If not, see <http://www.gnu.org/licenses/>. *
	*                                                                       *
	* Additional Terms, compatible with Section 7 of the GNU GPL v3,        *
	* apply to X7 Chat 3 and all X7 Chat 3 files, including this one.       *
	* You should have received a copy of these Additional Terms in the      *
	* file docs/COPYING.ADDITIONAL_TERMS.  If you did not receive a copy    *
	* please visit <http://www.x7chat.com/COPYING.ADDITIONAL_TERMS/>.       *
	************************************************************************/

	class lib_room extends lib_clientsidedb {

		function lib_room($initial_id,$getby='rid'){
			if(!is_numeric($initial_id) && $getby == 'rid') $getby = 'name';
			parent::lib_clientsidedb($initial_id,$getby,'rid','rooms');
		}

		function get_output(){
			return array(
					'rid'=>$this->data_cache['rid'],
					'name'=>$this->data_cache['name'],
					'perms'=>$this->data_cache['perms'],
				);
		}
		
		public function has_permission(&$user,$permission,$pgroup=null){
			
			if($pgroup == null){
				if(!isset($GLOBALS['PERMS'][$permission]))
					trigger_error($GLOBALS['LANG']->lang_global->permission_does_not_exist.$permission,E_USER_ERROR);
			
				return $this->has_permission($user,$GLOBALS['PERMS'][$permission][1],$GLOBALS['PERMS'][$permission][0]);
			}
			
			if($user->permission_denied($permission,$pgroup))
				return false;
				
			$lperms = $this->get_local_pgroup_perms($user->data_cache['uid'],$user->data_cache['group'],$pgroup);
			
			return ($user->has_permission($permission,$pgroup) || ($permission & $lperms['allowed'] &~ $lperms['denied']));
				
		}
		
		public function permission_denied(&$user,$permission,$pgroup=null){
			
			if($pgroup == null){
				if(!isset($GLOBALS['PERMS'][$permission]))
					trigger_error($GLOBALS['LANG']->lang_global->permission_does_not_exist.$permission,E_USER_ERROR);
				
				return $this->permission_denied($user,$GLOBALS['PERMS'][$permission][1],$GLOBALS['PERMS'][$permission][0]);
			}
				
			if($user->permission_denied($permission,$pgroup))
				return true;
			
			$lperms = $this->get_local_pgroup_perms($user->data_cache['uid'],$user->data_cache['group'],$pgroup);
			
			return ($permission & $lperms['denied']);
			
		}
		
		private function get_local_pgroup_perms($userid,$groupid,$pgroup){
			$luperms = isset($this->data_cache['perms']['user'][$userid][$pgroup]) ? $this->data_cache['perms']['user'][$userid][$pgroup] : array('allowed'=>0,'denied'=>0);
			$lgperms = isset($this->data_cache['perms']['group'][$groupid][$pgroup]) ? $this->data_cache['perms']['group'][$groupid][$pgroup] : array('allowed'=>0,'denied'=>0);
			$defperms = isset($this->data_cache['perms']['default'][0][$pgroup]) ? $this->data_cache['perms']['default'][0][$pgroup] : array('allowed'=>0,'denied'=>0);
			return array('allowed'=>($luperms['allowed']|$lgperms['allowed']|$defperms['allowed']),'denied'=>($luperms['denied']|$lgperms['denied']|$defperms['denied']));
		}
		
		public function set_permission($permission,$mode,$setfor=null,$pgroup=null){
			
			if($pgroup == null){
				if(!isset($GLOBALS['PERMS'][$permission]))
					trigger_error($GLOBALS['LANG']->lang_global->permission_does_not_exist.$permission,E_USER_ERROR);
				
				return $this->set_permission($GLOBALS['PERMS'][$permission][1],$mode,$setfor,$GLOBALS['PERMS'][$permission][0]);
			}
			
			if(get_class($setfor) == 'lib_user'){
				$type = 'user';
				$id = $setfor->data_cache['uid'];
			}elseif(get_class($setfor) == 'lib_group'){
				$type = 'group';
				$id = $setfor->data_cache['gid'];
			}else{
				$type = 'default';
				$id = 0;
			}
			
			if(!isset($this->data_cache['perms'][$type][$id][$pgroup]))
				$this->data_cache['perms'][$type][$id][$pgroup] = array('allowed'=>0,'denied'=>0);
				
			$this->data_cache['perms'][$type][$id][$pgroup]['allowed'] &=~ $permission;
			$this->data_cache['perms'][$type][$id][$pgroup]['denied'] &=~ $permission;
				
			switch($mode){
				case -1:
					// Set to denied
					$this->data_cache['perms'][$type][$id][$pgroup]['denied'] |= $permission;
				break;
				case 1:
					// Set to allow
					$this->data_cache['perms'][$type][$id][$pgroup]['allowed'] |= $permission;
				break;
				default:
					// Check to see if this is null
					if($this->data_cache['perms'][$type][$id][$pgroup]['allowed'] == 0 && $this->data_cache['perms'][$type][$id][$pgroup]['denied'] == 0)
						unset($this->data_cache['perms'][$type][$id][$pgroup]);
					if(empty($this->data_cache['perms'][$type][$id]))
						unset($this->data_cache['perms'][$type][$id]);
				break;
			}
			
		}
		
		public function local_permission_value($getfor,$permission,$group=null){
			
			if(get_class($getfor) == 'lib_user'){
				$type = 'user';
				$id = $getfor->data_cache['uid'];
			}elseif(get_class($getfor) == 'lib_group'){
				$type = 'group';
				$id = $getfor->data_cache['gid'];
			}else{
				$type = 'default';
				$id = 0;
			}
			
			if($group == null){
				
				if(!isset($GLOBALS['PERMS'][$permission]))
					trigger_error($GLOBALS['LANG']->lang_global->permission_does_not_exist.$permission,E_USER_ERROR);
			
				return $this->local_permission_value($getfor,$GLOBALS['PERMS'][$permission][1],$GLOBALS['PERMS'][$permission][0]);
			}
			
			if(!isset($this->data_cache['perms'][$type][$id][$group])){
				$this->data_cache['perms'][$type][$id][$group] = array('allowed'=>0,'denied'=>0);
			}
				
			if($permission & $this->data_cache['perms'][$type][$id][$group]['allowed'])
				return 1;
			elseif($permission & $this->data_cache['perms'][$type][$id][$group]['denied'])
				return -1;
			else
				return 0;
			
		}

		function get_online_users(){
			global $settings;

			$output = array();
			$dir = $GLOBALS['CACHE']->get_group_iterator("online/{$this->data_cache['rid']}");
			while($uid = $dir->get_next()){
				$ud = new lib_user(basename($uid));

				if($GLOBALS['CACHE']->gettime($uid) < time()-$settings['online_expire_seconds']){
					$this->part($ud);
				}else{
					$output[basename($uid)] = $ud;
				}
			}

			return $output;
		}

		// TODO: Test ban expiration and make sure it works, especially the forever ban
		function check_ban_expiration($uid){
			if(!isset($this->data_cache['ban_data']['u'.$uid]) || ($this->data_cache['ban_data']['u'.$uid] != 0 && time() > $this->data_cache['ban_data']['u'.$uid])){
				//$this->unban_user($uid,true);
				lib_room_extended::set_permissions_mode($this,$uid,'user','unban',true);
				return true;
			}else
				return false;
		}

		function remove(){
			$GLOBALS['CACHE']->remove("messages/{$this->data_cache['rid']}");
			$GLOBALS['CACHE']->remove_group("online/{$this->data_cache['rid']}");
			parent::remove();
		}

		function part($user){
			if(!$user->is_valid())
				$user->data_cache['uid'] = (int)$user->initial_id;

			$GLOBALS['CACHE']->remove("online/{$this->data_cache['rid']}/{$user->data_cache['uid']}");
			$GLOBALS['CACHE']->write("messages/{$this->data_cache['rid']}",array('lastUpdateTime'=>microtime_float(),'operation'=>'online_remove','data'=>array('uid'=>$user->data_cache['uid'],'rid'=>$this->data_cache['rid'])));
		}

		function join_room(){
			global $ses;
			$GLOBALS['CACHE']->write("messages/{$this->data_cache['rid']}",array('lastUpdateTime'=>microtime_float(),'database'=>'users','operation'=>'add','index'=>$ses->user->data_cache['uid'],'data'=>$ses->user->get_output()));
			$GLOBALS['CACHE']->write("messages/{$this->data_cache['rid']}",array('lastUpdateTime'=>microtime_float(),'operation'=>'online_add','data'=>array('uid'=>$ses->user->data_cache['uid'],'name'=>$ses->user->data_cache['name'],'rid'=>$this->data_cache['rid'],'status'=>$ses->user->data_cache['status'])));
		}
		
	}

?>